#include <A_Config.h>
AppManager appManager;

AppBase::AppBase()
{
    appID = appManager.getAValidAppID();
    appManager.increaseValidAppID();
    appManager.appList.push_back(this);
}
AppBase::~AppBase()
{
    appManager.appList.remove(this);
}

void AppBase::loop()
{
    if (hal.axpShortPress)
    {
        hal.axpShortPress = false;
        appManager.goBack();
        return;
    }
};

lv_obj_t *AppManager::createAppScr()
{
    lv_obj_t *app_scr = lv_obj_create(NULL);
    return app_scr;
}
int AppManager::getIDByName(const char *appName)
{
    for (std::list<AppBase *>::iterator iter = appList.begin(); iter != appList.end(); iter++)
    {
        if (strcmp((*iter)->name, appName) == 0)
            return (*iter)->appID;
    }
    return -1;
}

void AppManager::gotoApp(int appID)
{
    AppBase *app_to = NULL;
    for (std::list<AppBase *>::iterator iter = appList.begin(); iter != appList.end(); iter++)
    {
        if ((*iter)->appID == appID)
        {
            app_to = *iter;
            break;
        }
    }
    if (app_to == NULL)
        return;
    appStack.push(currentApp);
    method = APPMANAGER_GOTOAPP;
    currentApp = app_to;
}

void AppManager::goBack()
{
    AppBase *app_to = NULL;
    if (appStack.empty() == true)
    {
        return;
    }
    method = APPMANAGER_GOBACK;
    currentApp = appStack.top();
    appStack.pop();
}

////////////////////////////////////////////////////////////////

// APPList部分
static enum {
    APPSELECTOR_NOT_RUN = 0,
    APPSELECTOR_RUNNING,
    APPSELECTOR_FINISHED,
    APPSELECTOR_ERROR,
    APPSELECTOR_MAX
} appSelector_status;
static int appSelector_chooseID = 0;
static lv_obj_t *appSelector_Create()
{
    lv_obj_t *obj_appSelector = lv_obj_create(NULL);
    lv_obj_set_style_pad_all(obj_appSelector, 6, 0);
    lv_obj_center(obj_appSelector);
    lv_obj_set_flex_flow(obj_appSelector, LV_FLEX_FLOW_COLUMN_WRAP);
    lv_obj_set_scroll_dir(obj_appSelector, LV_DIR_LEFT | LV_DIR_RIGHT);
    return obj_appSelector;
}

static void event_btn(lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *obj = lv_event_get_target(e);
    switch (code)
    {
    case LV_EVENT_RELEASED:
        lv_obj_scroll_to_view(obj, LV_ANIM_ON);
        break;
    case LV_EVENT_PRESSED:
        lv_obj_clear_state(obj, LV_STATE_USER_2);
        break;
    case LV_EVENT_CLICKED:
        // 选择了app，跳转
        if (lv_obj_has_state(obj, LV_STATE_USER_2)) // 如果是长按
            break;
        // 否则就是短按
        appSelector_chooseID = (int)lv_event_get_user_data(e);
        appSelector_status = APPSELECTOR_FINISHED;
        break;
    case LV_EVENT_DEFOCUSED:
        // 离开按钮，如果已经放大则缩小按钮  120*170->50*50
        if (lv_obj_has_state(obj, LV_STATE_USER_1))
        {
            lv_anim_t a;
            lv_anim_init(&a);
            lv_anim_set_var(&a, obj);
            lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
            lv_anim_set_time(&a, 300);

            lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_width);
            lv_anim_set_values(&a, 120, 50);
            lv_anim_start(&a);

            lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_height);
            lv_anim_set_values(&a, 170, 50);
            lv_anim_start(&a);

            lv_anim_set_var(&a, lv_obj_get_child(obj, 2));
            lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_y);
            lv_anim_set_values(&a, 20, 0);
            lv_anim_start(&a);

            lv_obj_add_flag(lv_obj_get_child(obj, 0), LV_OBJ_FLAG_HIDDEN);
            lv_obj_add_flag(lv_obj_get_child(obj, 1), LV_OBJ_FLAG_HIDDEN);

            lv_obj_clear_state(obj, LV_STATE_USER_1);
        }
        break;
    case LV_EVENT_LONG_PRESSED:
        // 长按，如果之前没有放大则放大   50*50->120*170
        if (lv_obj_has_state(obj, LV_STATE_USER_1) == false)
        {
            lv_anim_t a;
            lv_anim_init(&a);
            lv_anim_set_var(&a, obj);
            lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
            lv_anim_set_time(&a, 400);

            lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_width);
            lv_anim_set_values(&a, 50, 120);
            lv_anim_start(&a);

            lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_height);
            lv_anim_set_values(&a, 50, 170);
            lv_anim_start(&a);

            lv_anim_set_var(&a, lv_obj_get_child(obj, 2));
            lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_y);
            lv_anim_set_values(&a, 0, 20);
            lv_anim_start(&a);

            lv_obj_clear_flag(lv_obj_get_child(obj, 0), LV_OBJ_FLAG_HIDDEN);
            lv_obj_clear_flag(lv_obj_get_child(obj, 1), LV_OBJ_FLAG_HIDDEN);
            lv_obj_add_state(obj, LV_STATE_USER_1);

            // 设置长按标志
            lv_obj_add_state(obj, LV_STATE_USER_2);
        }
    default:
        break;
    }
}

static void appSelector_add(lv_obj_t *obj, const char *title, const char *desc, const void *img_desc, int appID)
{
    lv_obj_t *btn_obj = lv_btn_create(obj);
    lv_obj_set_size(btn_obj, 50, 50);
    lv_obj_set_style_pad_all(btn_obj, 6, 0);

    lv_obj_t *lbl_title = lv_label_create(btn_obj);
    lv_obj_set_style_text_font(lbl_title, &lv_font_chinese_16, 0);
    lv_label_set_text(lbl_title, title);
    lv_obj_align(lbl_title, LV_ALIGN_TOP_MID, 0, 0);
    lv_obj_add_flag(lbl_title, LV_OBJ_FLAG_HIDDEN);

    lv_obj_t *lbl_desc = lv_label_create(btn_obj);
    lv_obj_set_style_text_font(lbl_desc, &lv_font_chinese_16, 0);
    lv_label_set_text(lbl_desc, desc);
    lv_obj_align(lbl_desc, LV_ALIGN_BOTTOM_MID, 0, 0);
    lv_label_set_long_mode(lbl_desc, LV_LABEL_LONG_WRAP);
    lv_obj_set_size(lbl_desc, 100, 100);
    lv_obj_set_style_text_align(lbl_desc, LV_TEXT_ALIGN_AUTO, 0);
    lv_obj_add_flag(lbl_desc, LV_OBJ_FLAG_HIDDEN);

    lv_obj_t *img = lv_img_create(btn_obj);
    lv_obj_set_size(img, 36, 36);
    lv_obj_set_style_text_font(img, &app_icon_28, 0);
    lv_obj_align(img, LV_ALIGN_TOP_MID, 0, 0);
    lv_img_set_src(img, img_desc);

    lv_obj_add_event_cb(btn_obj, event_btn, LV_EVENT_ALL, (int *)appID); // 这里用指针存了个整数（反正都是4字节）
}

void AppManager::showAppList()
{
    appselector = appSelector_Create();
    lv_scr_load_anim(appselector, LV_SCR_LOAD_ANIM_FADE_ON, 400, 0, false);
    for (std::list<AppBase *>::iterator iter = appList.begin(); iter != appList.end(); iter++)
    {
        appSelector_add(appselector, (*iter)->title, (*iter)->description, (*iter)->image, (*iter)->appID);
    }
}

void AppManager::update()
{
    static int appClock_appID = -1;
    if (hal.axpLongPress)
    {
        hal.axpLongPress = false;
        appSelector_status = APPSELECTOR_RUNNING;
        appSelector_chooseID = 0;
        showAppList();
    }

    if (appSelector_status == APPSELECTOR_RUNNING)
    {
        if (hal.axpShortPress)
        {
            hal.axpShortPress = false;
            appSelector_status = APPSELECTOR_ERROR;
        }
    }
    else if (appSelector_status == APPSELECTOR_ERROR || appSelector_status == APPSELECTOR_FINISHED)
    {
        hal.axpShortPress = false;
        if (appSelector_status == APPSELECTOR_FINISHED)
        {
            if (currentApp == NULL || appSelector_chooseID != currentApp->appID)
                gotoApp(appSelector_chooseID);
            else
            {
                lv_scr_load_anim(currentApp->scr, LV_SCR_LOAD_ANIM_FADE_ON, 300, 0, true);
                appselector = NULL;
            }
        }
        else
        {
            lv_scr_load_anim(currentApp->scr, LV_SCR_LOAD_ANIM_FADE_ON, 300, 0, true);
            parameter = "";
            appselector = NULL;
        }
        appSelector_status = APPSELECTOR_NOT_RUN;
    }
    // 下面是加载App
    static AppBase *last_app = NULL;
    if (last_app && appSelector_status != APPSELECTOR_RUNNING)
        last_app->loop();
    if (currentApp == last_app)
        return;

    hal.axpShortPress = hal.axpLongPress = false;
    if (method == APPMANAGER_GOTOAPP)
    {
        if (strcmp(currentApp->name, "clock") == 0 && last_app != NULL)
        {
            appClock_appID = currentApp->appID;
            last_app->destruct();
            if (lv_obj_is_valid(last_app->scr))
                lv_obj_del(last_app->scr);
            last_app->scr = NULL;
            while (1)
            {
                if (appStack.empty() == true)
                    break;
                AppBase *app = appStack.top();
                if (app == NULL)
                    break;
                app->destruct();
                if (lv_obj_is_valid(app->scr))
                {
                    lv_obj_del(app->scr);
                    app->scr = NULL;
                }
                appStack.pop();
            }
            last_app = currentApp;
            currentApp->scr = createAppScr();
            currentApp->setup();
            parameter = "";
            lv_scr_load_anim(currentApp->scr, LV_SCR_LOAD_ANIM_FADE_ON, 300, 0, true);
            return;
        }
        if (lv_obj_is_valid(currentApp->scr))
            lv_obj_del(currentApp->scr);
        currentApp->scr = createAppScr();
        if (last_app != NULL)
        {
            if (appselector == NULL)
                lv_scr_load_anim(currentApp->scr, LV_SCR_LOAD_ANIM_FADE_ON, 300, 0, false);
            else
                lv_scr_load_anim(currentApp->scr, LV_SCR_LOAD_ANIM_FADE_ON, 300, 0, true);
            appselector = NULL;
        }
        else
            lv_scr_load_anim(currentApp->scr, LV_SCR_LOAD_ANIM_NONE, 0, 0, true);
        last_app = currentApp;
        currentApp->setup(); // 这个要放在后面，不然如果有一直不返回的setup会卡住
        parameter = "";
    }
    if (method == APPMANAGER_GOBACK)
    {
        // 要求返回，这时要删除之前的scr
        last_app->destruct();
        lv_scr_load_anim(currentApp->scr, LV_SCR_LOAD_ANIM_FADE_ON, 300, 0, true);
        last_app->scr = NULL;
    }
    last_app = currentApp;
    if (currentApp->appID == appClock_appID)
    {
        hal.canDeepSleep = true;
    }
    else
    {
        hal.canDeepSleep = false;
    }
}
